package produce;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import produce.entity.User;

import javax.jms.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * @author xiaohong
 * @version 1.0
 * @date 2021/11/14 0014 16:57
 * @description 生产者
 */
@RestController
@RequestMapping("/send")
public class ProduceController {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private JmsTemplate jmsTemplate;

    /**
     * 发送文本消息
     * @return
     */
    @GetMapping("/text")
    public String textSender(){
        /**
         * 参数一 队列名称或主题名称
         * 参数二 消息内容
         */
        jmsMessagingTemplate.convertAndSend("queue","text");

        return "发送文本消息成功";
    }

    /**
     * 发送map消息
     * @return
     */
    @GetMapping("/map")
    public String mapSender(){
        jmsTemplate.send("queue", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                MapMessage mapMessage = session.createMapMessage();
                mapMessage.setString("name","张三");
                mapMessage.setInt("age",12);
                return mapMessage;
            }
        });

        return "发送map消息成功";
    }

    /**
     * 发送object消息
     * @return
     */
    @GetMapping("/object")
    public String objectSender(){
        jmsTemplate.send("queue", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                User user = new User();
                user.setUsername("xiaohong");
                user.setAge(18);
                ObjectMessage objectMessage = session.createObjectMessage(user);

                return objectMessage;
            }
        });

        return "发送对象消息成功";
    }

    /**
     * 发送字节消息
     * @return
     */
    @GetMapping("/byte")
    public String byteSender(){
        jmsTemplate.send("queue", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                BytesMessage bytesMessage = session.createBytesMessage();
                try {
                    // 读取文件
                    File file = new File("F:\\IDEA-workspace\\MQProject\\MQParent\\ActiveMQ\\activemq-produce\\src\\main\\resources\\a.txt");
                    // 构建文件输入流
                    FileInputStream fileInputStream = new FileInputStream(file);
                    // 将文件写入到缓存数组中
                    byte[] bytes = new byte[(int) file.length()];
                    fileInputStream.read(bytes);
                    // 将缓存数组写入到BytesMessage中
                    bytesMessage.writeBytes(bytes);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return bytesMessage;
            }
        });

        return "发送字节消息成功";
    }

    /**
     * 发送流消息
     * @return
     */
    @GetMapping("/stream")
    public String streamSender(){
        jmsTemplate.send("queue", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                StreamMessage streamMessage = session.createStreamMessage();
                streamMessage.writeString("我是一段流消息");
                streamMessage.writeInt(18);
                return streamMessage;
            }
        });

        return "发送流消息成功";
    }

    /**
     * 发送自定义消息头消息
     * @return
     */
    @GetMapping("/custom-head")
    public String customHeadSender(){

        jmsTemplate.send("queue", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage message = session.createTextMessage("custom-head");

                /**
                 * JMSDestination 消息发送的 Destination，在发送过程中由提供者设置
                 * JMSMessagelD 唯一标识提供者发送的每一条消息。这个字段是在发送过程中由提供者设置的，客户只能在消息发送后才能确定消息的JMSMessagelD
                 * JMSDeliveryMode 消息持久化。包含值DeliveryMode.PERSISTENT 或者 DeliveryMode.NON_PERSISTENT。
                 * JMSTimestamp 提供者发送消息的时间，由提供者在发送过程中设置
                 * JMSExpiration 消息失效的时间，毫秒，值О表明消息不会过期，默认值为0
                 * JMSPriority 消息的优先级，由提供者在发送过程中设置。优先级0的优先级最低，优先级9的优级最高。0-4为普通消息，5-9为加急消息。ActiveMQ不保证优先级高就一定先发送，保证了加急消息必须先于普通消息发送。默认值为4
                 * JMSCorrelationID 通常用来链接响应消息与请求消息，由发送消息的JMS程序设置。
                 * JMSReplyTo 请求程序用它来指出回复消息应发送的地方，由发送消息的JMS程序设置
                 * JMSType JMS程序用它来指出消息的类型。
                 * JMSRedelivered 消息的重发标志，false，代表该消息是第一次发生，true，代表该消息为重发消息
                 *
                 * 开发者只可以修改的有 JMSCorrelationID, JMSReplyTo, JMSType
                 *
                 */
                // 设置消息头
                message.setJMSMessageID("1000");
                message.setJMSPriority(9); // 不会修改
                message.setJMSCorrelationID("20000"); // 不会修改

                return message;
            }
        });

        return "发送自定义消息头的消息成功";
    }


    /**
     * 发送自定义消息属性消息
     * @return
     */
    @GetMapping("/custom-property")
    public String customPropertySender(){

        jmsTemplate.send("queue", new MessageCreator() {
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage message = session.createTextMessage("custom-property");
                // 设置消息属性： 标记、过滤
                message.setStringProperty("标记","我是一个标记");
                return message;
            }
        });

        return "发送自定义消息属性的消息成功";
    }


    /**
     * 发送消息 添加事务
     * @return
     */
    @GetMapping("/tx-message")
    @Transactional // 对消息发送加入事务管理（同时也对数据库的事务生效） 使用前记得加上配置文件
    public String transactionSender(){

        for (int i = 0; i < 10; i++) {
            // 如果不加事务，前三条会发送成功，后面的不会发送
            if (i == 3){
                // 模拟异常
                int a = 10/0;
            }
            jmsMessagingTemplate.convertAndSend("queue","message----"+i);
        }

        // 使用原生代码实现事务
//        // 获取连接工厂
//        ConnectionFactory connectionFactory = jmsMessagingTemplate.getConnectionFactory();
//        Session session = null;
//        try {
//            // 创建连接
//            Connection connection = connectionFactory.createConnection();
//
//            /**
//             * 参数一 是否开启事务
//             * 参数二 应答机制
//             */
//            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//
//            // 创建生产者
//            MessageProducer producer = session.createProducer(session.createQueue("queue"));
//
//            for (int i = 0; i < 10; i++) {
//
//                if (i == 3){
//                    // 模拟异常
//                    int a = 10/0;
//                }
//
//                TextMessage textMessage = session.createTextMessage("message----" + i);
//                producer.send(textMessage);
//            }
//
//            // 一旦事务发送，就必须使用commit方法进行事务提交，否则消息无法到达MQ服务器
//            session.commit();
//
//        } catch (JMSException e) {
//            e.printStackTrace();
//            // 消息回滚
//            try {
//                session.rollback();
//            } catch (JMSException ex) {
//                ex.printStackTrace();
//            }
//        }



        return "发送事务消息成功";
    }



}
